package com.css.fxfzypg.modules.rating.expertRating.service;

import cn.hutool.core.util.IdUtil;
import com.css.fxfzypg.modules.preassesstaskmanage.entity.PreAssessTaskEntity;
import com.css.fxfzypg.modules.preassesstaskmanage.service.PreAssessTaskService;
import com.css.fxfzypg.modules.rating.expertRating.constants.KpExpertRatingStatus;
import com.css.fxfzypg.modules.rating.expertRating.dao.KpRatingTaskExpertDao;
import com.css.fxfzypg.modules.rating.expertRating.dao.KpRatingTaskExpertScoreProgressDao;
import com.css.fxfzypg.modules.rating.expertRating.model.dto.SaveGlTaskScoreParam;
import com.css.fxfzypg.modules.rating.expertRating.model.entity.KpRatingTaskExpertScoreProgress;
import com.css.fxfzypg.modules.rating.expertRating.model.vo.*;
import com.css.fxfzypg.modules.rating.library.dao.KpExamScoringDbIndex3Repository;
import com.css.fxfzypg.modules.rating.library.model.entity.KpIndex3Data;
import com.css.fxfzypg.modules.rating.library.model.vo.KpExamScoringDbIndex1Vo;
import com.css.fxfzypg.modules.rating.library.model.vo.KpExamScoringDbIndex2Vo;
import com.css.fxfzypg.modules.rating.library.model.vo.KpExamScoringDbIndex3Vo;
import com.css.fxfzypg.modules.rating.library.service.KpExamScoringDbService;
import com.css.fxfzypg.modules.rating.library.service.KpIndex3DataService;
import com.css.fxfzypg.modules.rating.library.service.cache.KpIndex3DataCacheService;
import com.css.fxfzypg.modules.rating.task.dao.*;
import com.css.fxfzypg.modules.rating.task.model.entity.*;
import com.css.fxfzypg.modules.resultManagement.reportManagement.entity.FieldHistoryUploadReport;
import com.css.fxfzypg.modules.resultManagement.reportManagement.entity.HistoryUploadReport;
import com.css.fxfzypg.modules.resultManagement.reportManagement.service.ReportManagementService;
import com.css.fxfzypg.modules.resultManagement.reportManagement.service.SamplingSurveyReportService2;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;

/**
 * 专家评分管理
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class KpExpertRatingService {
    @Autowired
    private KpRatingTaskExpertDao kpRatingTaskExpertDao;
    @Autowired
    KpRatingTaskRepository kpRatingTaskRepository;
    @Autowired
    KpRatingTaskYpgTaskRepository kpRatingTaskYpgTaskRepository;
    @Autowired
    KpRatingTaskExpertScoreProgressDao kpRatingTaskExpertScoreProgressDao;
    @Autowired
    KpRatingTaskAreaRepository kpRatingTaskAreaRepository;
    @Autowired
    private KpExamScoringDbService kpExamScoringDbService;
    @Autowired
    KpRatingTaskIndex3ScoreRepository kpRatingTaskIndex3ScoreRepository;
    @Autowired
    KpRatingTaskIndex3ScoreExpertRepository kpRatingTaskIndex3ScoreExpertRepository;
    @Autowired
    private KpExamScoringDbIndex3Repository kpExamScoringDbIndex3Repository;
    @Autowired
    private ReportManagementService reportManagementService;
    @Autowired
    private SamplingSurveyReportService2 samplingSurveyReportService;
    @Autowired
    PreAssessTaskService preAssessTaskService;
    @Autowired
    KpIndex3DataCacheService kpIndex3DataCacheService;
    @Autowired
    KpRatingTaskProgressRepository kpRatingTaskProgressRepository;

    /**
     * 查询考评任务
     *
     * @param expertId 专家id
     * @return
     */
    public List<KpRatingTask> list(String expertId) {
        return kpRatingTaskExpertDao.getKpRatingTaskByExpertId(expertId);
    }

    public KpRatingTaskByKrtIdVo getKpRatingTaskByKrtId(String krtId, String currUid) {
        KpRatingTask kpRatingTask = kpRatingTaskRepository.getById(krtId);
        if (kpRatingTask == null) {
            return null;
        }
        KpRatingTaskByKrtIdVo vo = new KpRatingTaskByKrtIdVo();
        vo.setKrtId(kpRatingTask.getId());
        vo.setName(kpRatingTask.getName());
        vo.setEndDate(kpRatingTask.getEndDate());
        vo.setGlTask(this.getGlTaskList(krtId, currUid));
        return vo;
    }

    private List<KpRatingTaskByKrtIdVo.GlTask> getGlTaskList(String krtId, String expertId) {
        List<KpRatingTaskByKrtIdVo.GlTask> kpGlTaskExpert = kpRatingTaskYpgTaskRepository.getKpGlTaskExpert(krtId, expertId);
        if (kpGlTaskExpert != null) {
            kpGlTaskExpert.forEach(o -> {
                KpExpertRatingStatus status = KpExpertRatingStatus.getByCode(o.getStatus());
                if (status != null) {
                    o.setStatusStr(status.getRemark());
                }
                o.setJbReportName(Optional.ofNullable(reportManagementService.getHistoryById(o.getJbReportId())).map(HistoryUploadReport::getReportName).orElse(null));
                o.setXbReportName(Optional.ofNullable(reportManagementService.getHistoryById(o.getXbReportId())).map(HistoryUploadReport::getReportName).orElse(null));
                o.setXcdcReportName(Optional.ofNullable(samplingSurveyReportService.getHistoryById(o.getXcdcReportId())).map(FieldHistoryUploadReport::getReportName).orElse(null));
                o.setYpgName(Optional.ofNullable(preAssessTaskService.getById(o.getYpgId())).map(PreAssessTaskEntity::getTaskName).orElse(null));
            });
        }
        return kpGlTaskExpert;
    }

    public Integer countSubmittedNum(List<String> currProvGlTaskIdList) {
        return kpRatingTaskExpertScoreProgressDao.countSubmittedNum(currProvGlTaskIdList);
    }

    /**
     * 查询某专家需要打分的关联任务的详情
     *
     * @param krtytId  关联任务id
     * @param expertId 专家id
     * @return
     */
    public ExpertScoreDetailsVo getGlTaskScoreDetails(String krtytId, String expertId) {
        KpRatingTaskYpgTask glTask = kpRatingTaskYpgTaskRepository.getById(krtytId);
        if (glTask == null) {
            log.warn("关联任务为空");
            return null;
        }
        BigDecimal totalExpertScore = BigDecimal.ZERO;
        List<ExpertScoreIndexVo> indexList = new ArrayList<>();
        // 查询关联任务下的指标
        List<KpExamScoringDbIndex1Vo> kpExamScoringDbIndex1VoList = kpExamScoringDbService.getIndexByKrtytId(krtytId);
        // 指标库下没有指标，构建任务名称和空的指标列表vo
        if (kpExamScoringDbIndex1VoList == null) {
            return ExpertScoreDetailsVo.builder().ypgId(glTask.getYpgTaskId()).ypgName(kpRatingTaskYpgTaskRepository.getYpgNameByKrtytId(krtytId)).totalExpertScore(totalExpertScore).indexList(indexList).build();
        }
        // 根据指标构建vo
        for (KpExamScoringDbIndex1Vo index1 : kpExamScoringDbIndex1VoList) {
            if (index1.getChildren() == null) {
                indexList.add(ExpertScoreIndexVo.builder().index1Id(index1.getId()).index1Name(index1.getName()).index1Score(index1.getScore()).build());
                continue;
            }
            BigDecimal index1Score = kpExamScoringDbIndex3Repository.sumScoreByKesdi1Id(index1.getId());
            for (KpExamScoringDbIndex2Vo index2 : index1.getChildren()) {
                if (index2.getChildren() == null) {
                    indexList.add(ExpertScoreIndexVo.builder().index1Id(index1.getId()).index1Name(index1.getName()).index1Score(index1.getScore()).index2Id(index2.getId()).index2Name(index2.getName()).index2Score(index2.getScore()).build());
                    continue;
                }
                double index2Score = index2.getChildren().stream().mapToDouble(o -> o.getScore().doubleValue()).sum();
                for (KpExamScoringDbIndex3Vo index3 : index2.getChildren()) {
                    KpIndex3Data kpIndex3Data = index3.getKpIndex3Data();
                    // 查询某专家给当前关联任务打的三级指标的分数
                    KpRatingTaskIndex3ScoreExpert kpRatingTaskIndex3ScoreExpert = kpRatingTaskIndex3ScoreRepository.getByExpertIdAndKesdi3IdAndKrtytId(expertId, index3.getId(), krtytId);
                    BigDecimal expertScore = BigDecimal.ZERO;
                    if (kpRatingTaskIndex3ScoreExpert != null && kpRatingTaskIndex3ScoreExpert.getScore() != null) {
                        expertScore = kpRatingTaskIndex3ScoreExpert.getScore();
                    }
                    // 计算专家得分的总分数
                    totalExpertScore = totalExpertScore.add(expertScore);
                    indexList.add(ExpertScoreIndexVo.builder().index1Id(index1.getId()).index1Name(index1.getName()).index1Score(index1Score).index2Id(index2.getId()).index2Name(index2.getName()).index2Score(BigDecimal.valueOf(index2Score)).index3Id(index3.getId()).index3Score(index3.getScore()).index3Standard(index3.getIndexStandard()).kpIndex3Data(kpIndex3Data).expertScore(expertScore).build());
                }
            }
        }
        return ExpertScoreDetailsVo.builder().ypgId(glTask.getYpgTaskId()).ypgName(kpRatingTaskYpgTaskRepository.getYpgNameByKrtytId(krtytId)).totalExpertScore(totalExpertScore).indexList(indexList).build();
    }

    public void saveGlTaskScore(SaveGlTaskScoreParam saveGlTaskScoreParam, String expertId) {
        if (StringUtils.isBlank(saveGlTaskScoreParam.getKrtytId())) {
            throw new RuntimeException("krtytId 不能为空");
        }
        KpRatingTaskExpertScoreProgress progress = kpRatingTaskExpertScoreProgressDao.getByExpertAndKrtytId(saveGlTaskScoreParam.getKrtytId(), expertId);
        if (progress != null && progress.getStatus() == KpExpertRatingStatus.STOP.getCode()) {
            throw new RuntimeException("评分已停止");
        }
        for (SaveGlTaskScoreParam.IndexScore param : saveGlTaskScoreParam.getIndexScoreList()) {
            KpIndex3Data kpIndex3Data = kpIndex3DataCacheService.getById(param.getKi3dId());
            if (kpIndex3Data == null) {
                throw new RuntimeException("错误的指标id");
            }
            if (kpIndex3Data.getIsSystem() == 1) {
                continue;
            }
            KpRatingTaskIndex3ScoreExpert expertScore = kpRatingTaskIndex3ScoreExpertRepository.getByKrtytyIdAndExpertIdAndKesdi3Id(saveGlTaskScoreParam.getKrtytId(), expertId, param.getIndex3Id());
            if (expertScore == null) {
                expertScore = new KpRatingTaskIndex3ScoreExpert();
                expertScore.setId(IdUtil.simpleUUID());
                expertScore.setExpertId(expertId);
                expertScore.setScore(param.getExpertScore());
                expertScore.setKesdi3Id(param.getIndex3Id());
                expertScore.setKrtytId(saveGlTaskScoreParam.getKrtytId());
                kpRatingTaskIndex3ScoreExpertRepository.insert(expertScore);
            } else {
                if (expertScore.getScore().equals(param.getExpertScore())) {
                    continue;
                }
                expertScore.setScore(param.getExpertScore());
                kpRatingTaskIndex3ScoreExpertRepository.updateById(expertScore);
            }
        }
        if (progress == null) {
            throw new RuntimeException("找不到考评任务评分状态");
        }
        progress.setStatus(1);
        Date commitTime = new Date();
        progress.setCommitTime(commitTime);
        kpRatingTaskExpertScoreProgressDao.updateById(progress);
    }

    /**
     * 提交考评任务
     *
     * @param krtytId 关联任务id
     */
    public void commit(String krtytId, String expertId) {
        KpRatingTaskExpertScoreProgress kpRatingTaskExpertScoreProgress = kpRatingTaskExpertScoreProgressDao.getByExpertAndKrtytId(krtytId, expertId);
        if (kpRatingTaskExpertScoreProgress == null) {
            throw new RuntimeException("找不到考评任务评分状态");
        }
        kpRatingTaskExpertScoreProgress.setStatus(2);
        Date commitTime = new Date();
        kpRatingTaskExpertScoreProgress.setCommitTime(commitTime);
        kpRatingTaskExpertScoreProgress.setIsCommit(1);
        kpRatingTaskExpertScoreProgressDao.updateById(kpRatingTaskExpertScoreProgress);
    }

}
